<?php
class Pageley_Serializer_Converter_Factory {
	private static $instance;
	private $boolean;
	private $timestamp;
	private $default;
	private $reference;
	private $file;
	private $enumerations;
	private $lists;

	private function __construct() {
		$this->boolean = new Pageley_Serializer_Converter_Boolean();
		$this->timestamp = new Pageley_Serializer_Converter_Timestamp();
		$this->default = new Pageley_Serializer_Converter_Default();
		$this->reference = new Pageley_Serializer_Converter_Reference();
		$this->file = new Pageley_Serializer_Converter_File();
		$this->enumerations = new Pageley_Util_ArrayMap();
		$this->lists = new Pageley_Util_ArrayMap();
	}

	public static function getInstance() {
		if(self::$instance === null) {
			self::$instance = new Pageley_Serializer_Converter_Factory();
		}
		return self::$instance;
	}

	public function getConverter($attribute) {
		$converter = $this->default;
		if($attribute instanceof Pageley_Domain_Attribute_RequiredDecorator) {
			$attribute = $attribute->getDecoratedAttribute();
		}
		if($attribute instanceof Pageley_Domain_Attribute_Boolean) {
			$converter = $this->boolean;
		} else if($attribute instanceof Pageley_Domain_Attribute_Timestamp) {
			$converter = $this->timestamp;
		} else if($attribute instanceof Pageley_Domain_Attribute_Enumeration) {
			$converter = $this->getEnumerationConverter($attribute);
		} else if($attribute instanceof Pageley_Domain_Attribute_Reference) {
			$converter = $this->reference;
		} else if($attribute instanceof Pageley_Domain_Attribute_MultipleDecorator) {
			$converter = null;
		} else if($attribute instanceof Pageley_Domain_Attribute_File) {
			$converter = $this->file;
		}
		return $converter;
	}

	private function getEnumerationConverter($attribute) {
		$key = $attribute->getClassName();
		$converter = $this->enumerations->get($key);
		if($converter === null) {
			$converter = new Pageley_Serializer_Converter_Enumeration($attribute);
			$this->enumerations->put($key, $converter);
		}
		return $converter;
	}
	
	private function getMultipleConverter($attribute) {
		$innerAttribute = $attribute->getAttribute();
		$key = get_class($innerAttribute);
		$converter = $this->lists->get($key);
		if($converter === null) {
			$innerConverter = $this->getConverter($innerAttribute);
			$converter = new Pageley_Serializer_Converter_Multiple($innerConverter);
			$this->lists->put($key, $converter);
		}
		return $converter; 
	}
}